package com.jack.charging.order.service.Impl;

import com.jack.charging.common.pojo.JsonResult;
import com.jack.charging.common.pojo.param.GunStatusUpdateParam;
import com.jack.charging.common.pojo.utils.JsonUtils;
import com.jack.charging.common.pojo.vo.StationInfoVO;
import com.jack.charging.order.common.ChargingConstants;
import com.jack.charging.order.common.MqttConstants;
import com.jack.charging.order.feign.DeviceClient;
import com.jack.charging.order.feign.UserClient;
import com.jack.charging.order.mqtt.MqttProducer;
import com.jack.charging.order.quartz.DeviceCheckJob;
import com.jack.charging.order.service.OrderService;
import com.jack.charging.common.pojo.vo.UserInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerConfigException;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jack.charging.order.common.GunStatusConstants;
import com.jack.charging.order.pojo.dto.chargingDto;

/**
 * @author Jack
 * @date 2025/2/7 17:56
 * @see
 * @since
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private UserClient userClient;

    /**
     * 获取用户id
     */
    private UserInfoVO getUserInfoByOpenFeign(Integer userId) {
        JsonResult<UserInfoVO> result = userClient.getUserInfo(userId);
        return result.getData();
    }
    @Override
    public String createOrder(com.jack.charging.order.pojo.param.OrderAddParam orderAddParam) {
        log.debug("创建订单-orderService:入参:{}", orderAddParam);
        //1 生成订单号
        log.debug("创建订单-orderService:生成订单号");
        String orderNo = getOrderNo();
        log.debug("创建订单-orderService:生成订单号:{}", orderNo);

        //2 获取用户信息 车辆id
        Integer userId = orderAddParam.getUserId();
        log.debug("创建订单-orderService:获取用户信息:入参:{}", userId);
        UserInfoVO userInfo = getUserInfoByOpenFeign(userId);
        log.debug("创建订单-orderService:获取用户信息:入参:{},出参:{}", userId,userInfo);

        //3 修改 充电枪 的状态 为 使用中
        // 1 使用中 魔数 应该定义为常量或者枚举
        log.debug("创建订单-orderService:修改枪的状态为使用中:入参:枪id:{},状态:{}",
                orderAddParam.getGunId(),GunStatusConstants.GUN_STATUS_USING);
        Boolean success = updateGunStatus(orderAddParam.getGunId(),
                GunStatusConstants.GUN_STATUS_USING);
        log.debug("创建订单-orderService:修改枪的状态为使用中:入参:枪id:{},状态:{},出参:{}",
                orderAddParam.getGunId(),GunStatusConstants.GUN_STATUS_USING,success);

        //4 获取 场站信息
        log.debug("创建订单-orderService:获取场站信息:入参:{}", orderAddParam.getGunId());
        StationInfoVO stationInfo = getStationInfo(orderAddParam.getGunId());
        log.debug("创建订单-orderService:获取场站信息:入参:{},出参:{}", orderAddParam.getGunId(),stationInfo);

        log.debug("创建订单-orderService:入参:{},出参:{}", orderAddParam,orderNo);
        //5 发送消息给场站
        startCharging(orderNo,orderAddParam.getPileId(),orderAddParam.getGunId());
        log.debug("创建订单-orderService:入参:{},出参:{}", orderAddParam,orderNo);
        //6.创建设备检查任务，用来检查任务无响应
        log.debug("创建订单-orderService:创建设备检查任务");
        try{
            new DeviceCheckJob(orderNo);
        }catch (SchedulerException e){
            log.error("创建订单-orderService:创建设备检查任务失败:{}",e.getMessage());
        }
        return orderNo;
    }

    @Autowired
    private MqttProducer mqttProducer;
    private void startCharging(String orderNo,Integer pileId,Integer gunId){
        String topic = MqttConstants.TOPIC_START_CHARGING_PREFIX+pileId;
        chargingDto dto = new chargingDto();
        dto.setOrderNo(orderNo);
        dto.setPileId(pileId);
        dto.setGunId(gunId);
        dto.setMsg(ChargingConstants.START_CHARGING);
        log.debug("开始充电-orderService:发送消息:topic:{},消息:{}",topic,dto);
        mqttProducer.send(topic, JsonUtils.toJson(dto));
        log.debug("开始充电-orderService:发送消息:topic:{},消息:{},出参:{}",topic,dto,true);
    }
    @Autowired
    private DeviceClient deviceClient;
    private StationInfoVO getStationInfo(Integer gunId){
        JsonResult<StationInfoVO> result = deviceClient.getStationInfo(gunId);
        if (result != null) {
            return result.getData();
        }
        return null;
    }
    private Boolean updateGunStatus(Integer gunId,Integer status){
        GunStatusUpdateParam param = new GunStatusUpdateParam();
        param.setGunId(gunId);
        param.setStatus(status);
        JsonResult<Boolean> result = deviceClient.updateGunStatus(param);
        if (result != null) {
            return result.getData();
        }
        return false;
    }

    private String getOrderNo(){
        return "666";
    }
}
